import { requestClient, baseRequestClient } from '#/api/request'
import { ref } from 'vue'
import { randomNum, shortUuid } from '#/utils/random'
import jsSHA from 'jssha'
import { useUserStore, useSiteStore } from '@vben/stores'

interface UploadFileParams {
  file: File
  onError?: (error: Error) => void
  onProgress?: (progress: { percent: number }) => void
  onSuccess?: (data: any, file: File) => void
}
const qnConfig = ref({
  cdnUrl: '',
  upload: {
    url: '',
    token: '',
    key: '',
    mode: '',
    savename: '',
  },
})
const siteStore = useSiteStore()

const getqnConfig = async () => {
  const data = await requestClient.get('/admin/index/qnConfig')
  qnConfig.value = data
}

const getFileSha1 = async (file: File) => {
  const shaObj = new jsSHA('SHA-1', 'ARRAYBUFFER')
  shaObj.update(await file.arrayBuffer())
  return shaObj.getHash('HEX')
}

const getSaveName = (file: File, sha1: string) => {
  const fileSuffix = file.name.substring(file.name.lastIndexOf('.') + 1)
  const fileName = file.name.substring(0, file.name.lastIndexOf('.'))
  const dateObj = new Date()

  const replaceArr: Record<string, string | number> = {
    '{topic}': 'default',
    '{year}': dateObj.getFullYear(),
    '{mon}': ('0' + (dateObj.getMonth() + 1)).slice(-2),
    '{day}': dateObj.getDate(),
    '{hour}': dateObj.getHours(),
    '{min}': dateObj.getMinutes(),
    '{sec}': dateObj.getSeconds(),
    '{random}': shortUuid(),
    '{random32}': randomNum(32, 32),
    '{filename}': fileName.substring(0, 100),
    '{suffix}': fileSuffix,
    '{.suffix}': '.' + fileSuffix,
    '{filesha1}': sha1,
  }

  // 使用 qnConfig.value.upload.savename 作为模板进行替换
  let result = qnConfig.value.upload.savename
  Object.keys(replaceArr).forEach((key) => {
    result = result.replace(new RegExp(key, 'g'), String(replaceArr[key]))
  })

  return result.replace('/scm', 'scm')
}

export async function upload_file_qiniu({ file, onError, onProgress, onSuccess }: UploadFileParams) {
  try {
    onProgress?.({ percent: 0 })
    qnConfig.value = siteStore.site
    const sha1 = await getFileSha1(file)
    const fileKey = getSaveName(file, sha1)
    const data = new FormData()
    data.append('file', file)
    data.append('token', qnConfig.value.upload.token)
    data.append('key', fileKey)
    const res = await baseRequestClient
      .post<any>(qnConfig.value.upload.url, data, {
        params: { uuid: 'uuid' },
        headers: { 'Content-Type': 'multipart/form-data' },
      })
      .then((res) => {
        let url = '/' + res.data.key
        requestClient.post('/admin/Qiniu/callback', {
          name: file.name,
          sha1: res.data.hash,
          size: file.size,
          type: file.type,
          url: url,
        })
        // 调用 onSuccess 回调，传递上传结果数据
        onSuccess?.(url, file)
      })

    // /admin/index/qnConfig
  } catch (error) {
    onError?.(error instanceof Error ? error : new Error(String(error)))
  }
}
